<template>
  <div>
    <div ref="mapDiv" class="full-height full-width"></div>
    <!--底部选项-->
    <transition-fade>
      <div
        style="height: 50px"
        :class="ui.modelClass"
        class="absolute-bottom full-width justify-center flex"
      >
        <q-btn
          no-caps
          rounded
          unelevated
          style="margin: auto 15px"
          :class="ui.btnClass"
          :label="$t('MapCreate.退出建图')"
          @click="exitMap"
        />
        <q-btn
          no-caps
          rounded
          unelevated
          style="margin: auto 15px"
          :class="ui.btnClass"
          :label="$t('MapCreate.保存地图')"
          @click="saveMap"
        />
      </div>
    </transition-fade>
    <q-btn
      no-caps
      class="absolute text-space"
      :class="ui.modelClass"
      @click="showQrCode"
      style="top: 210px; right: 0; border-radius: 25px 0 0 25px"
    >
      {{ $t("MapCreate.远程遥控") }}
    </q-btn>
    <q-toggle
      no-caps
      class="absolute text-space"
      :class="ui.modelClass"
      v-if="useFunctionsStore().mode === 'remote'"
      v-model="keyboardMove"
      style="top: 280px; right: 0; border-radius: 25px 0 0 25px"
      label="键盘移动"
    >
    </q-toggle>
    <!--loading弹窗-->
    <q-inner-loading :showing="loading">
      <q-spinner-gears size="50px" color="primary" />
      <q-btn
        no-caps
        flat
        color="indigo"
        :label="$t('cancel')"
        class="q-ma-lg"
        @click="loading = false"
      />
    </q-inner-loading>
    <create-qr-code ref="qrCodeRef" />
  </div>
</template>

<script setup>
import { onMounted, onUnmounted, ref, watch } from "vue";
import { api } from "boot/axios";
import { useUiStore } from "stores/ui";
import { useAPIStore } from "stores/api";
import { useQuasar } from "quasar";
import { useRouter } from "vue-router";
import PixiMap from "src/utils/PixiMap";
import RosClient from "src/utils/rosClient";
import { isConnected, status } from "src/utils/deviceWs";
import TransitionFade from "components/animations/Fade.vue";
import CreateQrCode from "components/RemoteControl/CreateQrCode.vue";
import { useI18n } from "vue-i18n";
import { useFunctionsStore } from "stores/functions";

const t = useI18n().t;
const $q = useQuasar();
const ui = useUiStore();
const router = useRouter();
const pixiMap = PixiMap();
const rosClient = RosClient();
const mapDiv = ref();
const qrCodeRef = ref();
const loading = ref(false); // loading显示与否
const keyboardMove = ref(false); // 是否键盘操作

// ------生命周期----------------------------------------------------------------------
onMounted(() => {
  rosClient.createWs();
  initPixi();
  watch(
    () => status.value.createMap,
    (isCreateMap) => {
      if (!isCreateMap) {
        createMap();
      } else {
        $q.notify({
          message: t("正在建图中..."),
          type: "positive",
          position: "top-right",
        });
      }
    },
    {
      immediate: true,
    }
  );
  setKeyboard();
});

onUnmounted(() => {
  exit();
  rosClient.closeWs();
  pixiMap.destroyStage();
  document.onkeyup = null;
  document.onkeydown = null;
});

// ------监听-------------------------------------------------------------------------
// 监听设备位置
watch(rosClient.robotPose, (value) => {
  pixiMap.updateRobot(value);
});

// ------地图渲染----------------------------------------------------------------------
// 创建画布
function initPixi() {
  mapDiv.value.innerHTML = "";
  pixiMap.div = mapDiv.value;
  pixiMap.stage = pixiMap.createStage(mapDiv.value);
  initImg();
  loadRobot();
}

// 初始化素材
function initImg() {
  const poseImg = new Image();
  poseImg.src = "map/pose.png";
  window.URL.revokeObjectURL(poseImg.src);
  pixiMap.setPointStyle({ img: poseImg });
}

// 加载机器人
function loadRobot() {
  const robotImg = new Image();
  robotImg.src = "map/arrow.png";
  window.URL.revokeObjectURL(robotImg.src);
  // 机器人图片加载成功
  robotImg.onload = () => {
    // 渲染机器人
    pixiMap.robot = pixiMap.createRobot({ img: robotImg });
    pixiMap.updateStage();
    // 加载完毕后，视角落到机器人上
    pixiMap.focus();
    // 视角锁定机器人
    pixiMap.viewLocking = true;
    // 更新机器人位置
    rosClient.subscribe("/robot_pose");
  };
  rosClient.subscribe("/map_metadata");
}

// 加载建图中的地图
rosClient.loadMapData.value = (msg) => {
  // 加载地图
  const img = new Image();
  img.src =
    useAPIStore().rosImgUrl + "snapshot?topic=/map_image&rand=" + Math.random();
  window.URL.revokeObjectURL(img.src);
  img.crossOrigin = "Anonymous";
  img.onload = function () {
    // 渲染地图
    pixiMap.map = pixiMap.createMap({
      resolution: msg.resolution,
      x: msg.origin.position.x,
      y: msg.origin.position.y,
      img,
    });
    pixiMap.stage.removeChildAt(0);
    pixiMap.stage.addChildAt(pixiMap.map, 0);
  };
};

// ------事件函数----------------------------------------------------------------------
//  开启建图
function createMap() {
  api
    .get(useAPIStore().amrUrl + "map/new")
    .then((rs) => {
      if (rs.data.success) {
        $q.notify({
          message: t("MapCreate.开启建图成功"),
          type: "positive",
          position: "top-right",
        });
      } else {
        router.push("mapManage");
        $q.notify({
          message: t("MapCreate.开启建图失败"),
          type: "negative",
          position: "top-right",
        });
      }
    })
    .catch(() => {
      $q.notify({
        message: t("MapCreate.开启建图异常"),
        type: "negative",
        position: "top-right",
      });
    });
}

// 退出建图
function exitMap() {
  $q.dialog({
    dark: ui.isDark,
    title: t("MapCreate.是否退出建图"),
    ok: t("yes"),
    cancel: t("no"),
  }).onOk(() => {
    exit();
  });
}

function exit() {
  api.get(useAPIStore().amrUrl + "map/exit/create").then(() => {
    router.push("MapIndex");
    $q.notify({
      message: t("MapCreate.退出建图模式"),
      type: "positive",
      position: "top-right",
    });
  });
}

//  保存地图
function saveMap() {
  $q.dialog({
    dark: ui.isDark,
    title: t("MapCreate.保存地图"),
    message: t("MapCreate.请输入地图的名称"),
    prompt: {
      model: "",
      type: "text",
    },
    ok: {
      label: t("ok"),
      class: "text-bold",
      flat: true,
    },
    cancel: {
      label: t("cancel"),
      class: "text-bold",
      color: "secondary",
      flat: true,
    },
    persistent: true,
  }).onOk((data) => {
    if(!data){
      $q.notify({
        message: t("地图名称不能为空"),
        type: "negative",
        position: "top-right",
      });
      return;
    }
    loading.value = true;
    api
      .get(useAPIStore().amrUrl + "map/save", { params: { name: data } })
      .then((rs) => {
        if (rs.data.success) {
          api
            .get(useAPIStore().amrUrl + "map/set/" + rs.data.value)
            .then((rs) => {
              if (rs.data) {
                router.push("MapIndex");
                $q.notify({
                  message: t("MapCreate.保存地图成功"),
                  type: "positive",
                  position: "top-right",
                });
              }
            });
        } else {
          $q.notify({
            message: t("MapCreate.保存地图失败"),
            type: "negative",
            position: "top-right",
          });
        }
        loading.value = false;
      })
      .catch(() => {
        $q.notify({
          message: t("MapCreate.保存地图失败"),
          type: "negative",
          position: "top-right",
        });
      });
  });
}

//  显示二维码
function showQrCode() {
  if (isConnected.value) {
    if (status.value.network) {
      qrCodeRef.value.show(
        "http://" + status.value.network.IPv4 + "/#/RemoteControl"
      );
    } else {
      $q.notify({
        message: t("MapCreate.局域网未连接"),
        type: "negative",
      });
    }
  } else {
    $q.notify({
      message: t("MapCreate.设备未连接"),
      type: "negative",
    });
  }
}

/* --------------------------------------键盘移动--------------------------------------------------- */
const twist = ref({
  linear: {
    x: 0,
    y: 0,
    z: 0,
  },
  angular: {
    x: 0,
    y: 0,
    z: 0,
  },
});

function pubVel(x, z) {
  twist.value.linear.x = x;
  twist.value.angular.z = z;
  rosClient.publish("/device_send_raw", "SET_STATE,NORMAL｜～");
  rosClient.publish("/web/cmd_vel", twist.value);
}

const linear = ref(0);
const angular = ref(0);

function setKeyboard() {
  document.onkeydown = (e) => {
    if (keyboardMove.value) {
      switch (e.keyCode) {
        case 38:
          linear.value = 0.4;
          angular.value = 0;
          pubVel(linear.value, angular.value);
          break;
        case 40:
          linear.value = -0.4;
          angular.value = 0;
          pubVel(linear.value, angular.value);
          break;
        case 37:
          angular.value = 0.2;
          linear.value = 0;
          pubVel(linear.value, angular.value);
          break;
        case 39:
          angular.value = -0.2;
          linear.value = 0;
          pubVel(linear.value, angular.value);
          break;
      }
    }
  };
  document.onkeyup = (e) => {
    if (keyboardMove.value) {
      switch (e.keyCode) {
        case 38:
        case 40:
          linear.value = 0;
          break;
        case 37:
        case 39:
          angular.value = 0;
          break;
      }
    }
  };
}
</script>
